package midone.exchangeskill.net.api;

import android.text.TextUtils;
import android.util.Log;


import java.io.IOException;

import midone.exchangeskill.utils.LogLog;
import midone.exchangeskill.utils.NetWorkUtil;
import midone.exchangeskill.utils.SharedPreferencesUtil;
import midone.exchangeskill.utils.ViewUtils;
import okhttp3.CacheControl;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.http.HttpMethod;

/**
 * Created by 想法的猫 on 2016/8/29.
 * 日志拦截器  附带缓存处理
 */
public class LogInterceptor implements Interceptor {
    SharedPreferencesUtil sharedPreferencesUtil;
    ViewUtils viewUtils;
    NetWorkUtil netWorkUtil;
    final static String TAG = "responseContent";
    final static long cacheMaxAge = 3600 * 24 * 7;//本地缓存的最大时间
    final static String VERSION_PARAM = "version";//版本号参数 --- 公共参数

    public LogInterceptor(SharedPreferencesUtil sharedPreferencesUtil, ViewUtils viewUtils, NetWorkUtil netWorkUtil) {
        this.sharedPreferencesUtil = sharedPreferencesUtil;
        this.viewUtils = viewUtils;
        this.netWorkUtil = netWorkUtil;
    }

    @Override
    public Response intercept(Chain chain) {
        Request request = chain.request();
        String sid = sharedPreferencesUtil.getString(NetConstants.sidKey);
        //加入sid
        Request.Builder requestBuilder = request.newBuilder().cacheControl(shouldUseCache(request.headers()));
        if (!TextUtils.isEmpty(sid)) {
            requestBuilder.header(NetConstants.sidKey, sid);
        }
        request = addVersionParam(request, requestBuilder);
        Log.d(TAG, String.valueOf(request.url()));
        Response response = null;
        try {
            response = chain.proceed(request);
        } catch (IOException e) {
            e.printStackTrace();
            //如果接口调用失败则使用本地缓存
            request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
            try {
                response = chain.proceed(request);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        MediaType contentType = response.body().contentType();
        //非apk类型 返回类型需要对应json类型
        if (contentType != null)
            LogLog.log(TAG, "contentType=" + contentType.toString());
        if (contentType != null && contentType.toString().equals(NetConstants.JSON_TYPE)) {
            String responseBodyString = null;
            try {
                responseBodyString = response.body().string();
            } catch (IOException e) {
                e.printStackTrace();
            }
            interceptResponseCode(responseBodyString);
            ResponseBody responseBody = ResponseBody.create(contentType, responseBodyString);
            response = cacheConfig(response, responseBody);
        }
        return response;

    }

    /**
     * 统一加入version参数
     *
     * @param request
     * @param requestBuilder
     * @return
     */
    private Request addVersionParam(Request request, Request.Builder requestBuilder) {
        String versionValue = viewUtils.getVersionName();
        //对于文件流需要去除拼接version参数
        String noVersionParamHeader = request.header("noVersionParam");
        boolean noVersionParam = TextUtils.isEmpty(noVersionParamHeader) ? false : Boolean.parseBoolean(noVersionParamHeader);
        if (!noVersionParam) {
            //post区分
            boolean isPostMethod = HttpMethod.permitsRequestBody(request.method());
            if (isPostMethod && request.body() instanceof FormBody) {
                LogLog.log(TAG, request.body().toString());
                FormBody originalForm = (FormBody) request.body();
                //加入版本号参数
                FormBody formBody = addPublicParam(VERSION_PARAM, versionValue, originalForm);
                request = requestBuilder.method(request.method(), formBody).build();
            } else {
                request = requestBuilder.url(addGetParam(request.url().toString(), VERSION_PARAM, versionValue)).build();
            }
        }
        return request;
    }

    /**
     * 设置okHttp本地缓存信息
     *
     * @param response
     * @param responseBody
     * @return
     */
    private Response cacheConfig(Response response, ResponseBody responseBody) {
        Response.Builder builder = response.newBuilder();
        builder.body(responseBody).removeHeader("Pragma").removeHeader("Cache-Control");
        builder.header("Cache-Control", "public,max-age=" + cacheMaxAge);
        return builder.build();
    }

    /**
     * get方法拼接param
     *
     * @param url
     * @param param
     * @param value
     * @return
     */
    private String addGetParam(String url, String param, String value) {
        String contactStr = url.contains("?") ? "&" : "?";
        return url + contactStr + param + "=" + value;

    }

    /**
     * okHttp增加参数
     *
     * @param param
     * @param value
     */
    private FormBody addPublicParam(String param, String value, FormBody formBody) {
        FormBody.Builder formBodyBuilder = new FormBody.Builder();
        if (formBody == null) {
            formBody = formBodyBuilder.build();
        }
        for (int i = 0; i < formBody.size(); i++) {
            String paramName = formBody.encodedName(i);
            String paramValue = formBody.encodedValue(i);
            formBodyBuilder.add(paramName, paramValue);
        }
        formBodyBuilder.add(param, value);
        return formBodyBuilder.build();
    }

    /**
     * 检查网络状态 是否使用缓存
     *
     * @return
     */
    private CacheControl shouldUseCache(Headers headers) {
        boolean isConnected = netWorkUtil.isNetWorkConnect();
        return isConnected ? CacheControl.FORCE_NETWORK : CacheControl.FORCE_CACHE;
    }


    /**
     * 获取response 拿到code
     *
     * @param content
     */
    private static void interceptResponseCode(String content) {
        fullLog(content);
    }

    /**
     * 解决返回日志太长看不到问题
     *
     * @param responseInfo
     */
    private static void fullLog(String responseInfo) {
        if (responseInfo.length() > 4000) {
            int chunkCount = responseInfo.length() / 4000;     // integer division
            for (int i = 0; i <= chunkCount; i++) {
                int max = 4000 * (i + 1);
                if (max >= responseInfo.length()) {
                    Log.v(TAG, responseInfo.substring(4000 * i));
                } else {
                    Log.v(TAG, responseInfo.substring(4000 * i, max));
                }
            }
        } else {
            Log.v(TAG, responseInfo + "");
        }
    }

}
